package com.winchain.provider.expiration.service.impl;

import com.winchain.chainbill.bill.base.po.CbDct;
import com.winchain.chainbill.bill.base.po.CbOpt;
import com.winchain.chainbill.bill.base.po.CbRcv;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbSnd;
import com.winchain.chainbill.bill.base.po.CbXfe;
import com.winchain.chainbill.bill.biz.discount.service.BillDctAprvService;
import com.winchain.chainbill.bill.biz.discount.service.BillDctRevService;
import com.winchain.chainbill.bill.biz.receive.service.BillRcvAprvService;
import com.winchain.chainbill.bill.biz.receive.service.BillRcvService;
import com.winchain.chainbill.bill.biz.send.service.BillSndRevService;
import com.winchain.chainbill.bill.biz.send.vo.BatchBillStats;
import com.winchain.chainbill.bill.biz.transfer.service.BillXfeRevService;
import com.winchain.provider.expiration.rx.BillExpHandleSubscriber;
import com.winchain.provider.expiration.rx.BillExpirationEvent;
import com.winchain.provider.expiration.service.BillExpStateService;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import rx.Observable;

@Service("billExpStateService")
public class BillExpStateServiceImpl implements BillExpStateService {
	@Autowired
	private BillSndRevService billSndRevService;
	@Autowired
	private BillRcvService billRcvService;
	@Autowired
	private BillRcvAprvService billRcvAprvService;
	@Autowired
	BillXfeRevService billXfeRevService;
	@Autowired
	BillDctRevService billDctRevService;
	@Autowired
	private BillDctAprvService billDctAprvService;
	@Autowired
	private BillExpHandleSubscriber billExpHandleSubscriber;
	private final Log logger = LogFactory.getLog(getClass());
	private static final String ROLLBACK_REMARK = "����������������������";
	private static final String EXPIRE_REMARK = "������������";

	public void rollback(Collection<? extends CbRec> recs, boolean pm) {
		for (CbRec rec : recs) {
			rollback(rec, pm);
		}
	}

	public boolean rollback(CbRec rec) {
		return rollback(rec, false);
	}

	public boolean rollback(CbRec bill, boolean pm) {
		boolean stateChanged = false;
		String billState = bill.getBillState();
		CbOpt operation = new CbOpt();
		operation.setRemark("����������������������");
		String[] billIdArr = { bill.getBillId() };
		if ("S001".equals(billState)) {
			BatchBillStats<CbSnd> stats = this.billSndRevService.reject("����������������������", billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		} else if ("S002".equals(billState)) {
			stateChanged = true;
		} else if (("S003".equals(billState)) && (pm)) {
			BatchBillStats<CbRcv> stats = this.billRcvService.expDeny("����������������������", true, billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		} else if ("S025".equals(billState)) {
			BatchBillStats<CbRcv> stats = this.billRcvAprvService.expReject("����������������������", billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		} else if (("S023".equals(billState)) && (pm)) {
			stateChanged = true;
		} else if ("S006".equals(billState)) {
			BatchBillStats<CbXfe> stats = this.billXfeRevService.reject("����������������������", billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		} else if ("S032".equals(billState)) {
			stateChanged = true;
		} else if ("S013".equals(billState)) {
			BatchBillStats<CbDct> stats = this.billDctRevService.reject("����������������������", billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		} else if ("S020".equals(billState)) {
			BatchBillStats<CbDct> stats = this.billDctAprvService.reject("����������������������", billIdArr);
			if (billIdArr.length == stats.getAffectedRows()) {
				stateChanged = true;
			}
		}
		return stateChanged;
	}

	public void expire(Collection<? extends CbRec> bills) {
		try {
			for (CbRec bill : bills) {
				expire(bill);
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.logger.error("��������������������", e);
			throw new RuntimeException("��������������������", e);
		}
	}

	public void expire(CbRec bill) {
		String billState = bill.getBillState();
		CbOpt operation = new CbOpt();
		operation.setOptCode("E008");
		operation.setRemark("������������");
		if (("S005".equals(billState)) || ("S009".equals(billState)) || ("S017".equals(billState))
				|| ("S011".equals(billState)) || ("S012".equals(billState))) {
			BillExpirationEvent event = new BillExpirationEvent();
			event.setValue("bill", bill);
			event.setValue("operation", operation);
			Observable<BillExpirationEvent> observers = Observable.just(event);
			observers.subscribe(this.billExpHandleSubscriber);
		}
	}
}
